import { useEffect, useState } from "react";
import Taro, { useReachBottom, useRouter } from "@tarojs/taro";
import { ScrollView, View } from "@tarojs/components";

import {
  useBoolean,
  useCreation,
  useMap,
  useMount,
  useReactive,
  useToggle,
} from "ahooks";

import Page from "@/components/common/Page";
import Products from "./components/Products";
import ByIcon from "@/components/ui/ByIcon";
import ByButton from "@/components/ui/ByButton";
import Segmented from "@/components/app/Segmented";
import BySearchBar from "@/components/ui/BySearchBar";
import PageHeader from "@/components/common/PageHeader";

import useList from "@/hooks/useList";
import useFetch from "@/hooks/useFetch";
import ApiWorkflow from "@/api/workflow";
import ApiMaterial from "@/api/material";

import {
  MaterialChooseTemp,
  MaterialClassItem,
  MaterialDetailDTO,
  MaterialInfo,
} from "@/types/material";
import { TaskDetail } from "@/types/global";
import PopupCartList from "./components/PopupCartList";
import Sticky from "@/components/app/Sticky";
import PopupProductDetail from "./components/PopupProductDetail";

const tabs = [
  { label: "套内", value: true },
  { label: "套外", value: false },
];

export default () => {
  const [cartMaps, cartMapHandle] = useMap<string, MaterialDetailDTO>();

  const { params } = useRouter();

  // 是否套内
  const [isInPackage, setIsInPackage] = useState(true);

  const search = useReactive({
    keyword: "",
    materialClassCode: "",
  });

  const [contentHeight, setContentHeight] = useState<number>(300);

  useMount(() => {
    // 获取可滚动窗口高度
    const { screenHeight } = Taro.getWindowInfo();
    Taro.createSelectorQuery()
      .selectAll(".page-part")
      .boundingClientRect((res) => {
        const outHeight = (res as any[]).reduce(
          (sum = 0, item) => sum + item.height,
          0
        );
        setContentHeight(screenHeight - outHeight);
      })
      .exec();
  });

  // 获取材料分类
  const { list: classTreeList } = useList<MaterialClassItem[]>(
    ApiMaterial.classTree,
    {
      defaultParams: [{ materialProCode: "ZC" }],
      onSuccess(res) {
        // search.materialClassId = res[0]["materialClassId"];
        search.materialClassCode = res[0]["materialClassCode"];
      },
    }
  );

  // 根据条件，获取材料列表
  const { list, resetToFirst, nextPage } = useList<MaterialInfo[], [any]>(
    ApiMaterial.list,
    { manual: true }
  );

  // 根据意向客户ID获取材料模板
  const { data: materialInfo, run: getMaterialInfo } =
    useFetch<MaterialChooseTemp>(ApiMaterial.getMaterialInfoByintendId, "GET", {
      manual: true,
      onSuccess(res) {
        const newMap = new Map();
        // 把模板内的材料转成map形式
        res.Areas.forEach((area) => {
          area.DetailDTOList.forEach((item) => {
            item.MaterialCode && newMap.set(item.MaterialCode, item);
          });
        });
        cartMapHandle.setAll(newMap);
      },
    });

  // 获取工作流详情
  useFetch<TaskDetail>(ApiWorkflow.detail, "GET", {
    defaultParams: [{ workflowInstanceId: params.wl_id }],
    onSuccess(res) {
      getMaterialInfo({ intentCustomerId: res.intentCustomerId });
    },
  });

  useEffect(() => {
    if (search.materialClassCode) {
      resetToFirst(search);
    }
  }, [search.keyword, search.materialClassCode]);

  const [selectedProduct, setSelectedProduct] = useState<MaterialInfo | void>();
  const [cartVisible, handlerCartPopup] = useBoolean();

  // 提交按钮事件
  const handleSubmit = () => {
    Taro.navigateTo({
      url: `/packageProject/pages/material/confirmation?wl_id=${
        params.wl_id
      }&chooseMasterId=${materialInfo!.chooseMasterId}`,
      success(res) {
        res.eventChannel.emit(
          "acceptMaterialSelectedList",
          Array.from(cartMaps.values())
        );
      },
    });
  };

  const cartView = [...cartMaps.values()].reduce<{
    sum: number;
    amount: number;
  }>(
    (obj, item: MaterialDetailDTO) => {
      obj.sum += item.Num;
      obj.amount += item.Num * item.MaterialPrice;
      return obj;
    },
    { sum: 0, amount: 0 }
  );

  // 更新购物车材料数量
  const changeCartNum = (key: string, value: Partial<MaterialDetailDTO>) => {
    const target = cartMapHandle.get(key) || ({} as MaterialDetailDTO);

    cartMapHandle.set(key, {
      ...target,
      ...value,
    });
  };

  return (
    <>
      <Page
        slotHeader={
          <View className="page-part bg-page">
            <PageHeader title="装修选材" />

            <View className="flex items-center w-full px-3 pb-3 z-10 bg-page">
              <View className="flex-none w-[220px]">
                <Segmented
                  options={tabs}
                  active={isInPackage}
                  className="h-[64px]"
                  onSeleced={setIsInPackage}
                />
              </View>

              <View className="flex-auto mx-3">
                <BySearchBar
                  height="64rpx"
                  placeholder="搜索"
                  onClear={() => (search.keyword = "")}
                  onConfirm={(e) => (search.keyword = e)}
                />
              </View>

              <ByIcon className="flex-none" name="Scan" size={42} />
            </View>
          </View>
        }
        slotFooter={
          <Sticky className="z-[100]">
            <View className="relative page-part flex items-center w-full p-4 bg-[#667080] z-[1000]">
              <View className="relative" onClick={handlerCartPopup.setTrue}>
                <ByIcon name="Cart" size={56} color="#fff" />
                {cartView.sum > 0 && (
                  <View className="absolute top-0 min-w-[40px] h-[40px] px-1 flex-center rounded-full right-0 bg-[#23252a] text-white text-xs -translate-y-1/3 translate-x-1/2">
                    {cartView.sum}
                  </View>
                )}
              </View>

              <View className="flex-auto mx-6 text-white">
                ¥ {cartView.amount}
              </View>

              <ByButton rounded onClick={handleSubmit}>
                提交
              </ByButton>
            </View>
          </Sticky>
        }
      >
        <View className="relative overflow-hidden">
          <ScrollView
            scroll-y
            className="absolute top-0 bottom-0 left-0 w-[200px] bg-[#f1f3f8] z-10"
          >
            {classTreeList.map((item) => (
              <View
                key={item.materialClassCode}
                className={`h-[100px] flex-center ${
                  search.materialClassCode === item.materialClassCode
                    ? "bg-[#23252a] text-white"
                    : ""
                }`}
                onClick={() =>
                  (search.materialClassCode = item.materialClassCode)
                }
              >
                {item.materialClassName}
              </View>
            ))}
          </ScrollView>

          <ScrollView
            scroll-y
            onScrollToLower={nextPage}
            style={{ height: contentHeight + "px" }}
          >
            <View className="pl-[200px]">
              <View className="flex flex-wrap ">
                {list.map((item) => (
                  <Products
                    key={item.materialId}
                    source={item}
                    selected={cartMapHandle.get(item.materialCode) as any}
                    onSelected={() => setSelectedProduct(item)}
                  />
                ))}
              </View>
            </View>
          </ScrollView>
        </View>
      </Page>

      {cartVisible && (
        <PopupCartList
          source={cartMaps}
          onCancel={handlerCartPopup.setFalse}
          onChange={changeCartNum}
        />
      )}

      {selectedProduct && (
        <PopupProductDetail
          isInPackage={isInPackage}
          product={selectedProduct}
          areaList={materialInfo?.Areas}
          selected={cartMapHandle.get(selectedProduct.materialCode) as any}
          onCancel={() => setSelectedProduct()}
          onConfirm={(info) => cartMapHandle.set(info.MaterialCode, info)}
        />
      )}
    </>
  );
};
